		
	var DOM = {}
		
	Object.extend(Smernel, {
		
		version:'Adeliae',
		name:"Schrodinger's Penguin",
		usr:false,
		dom:false,
		secure:false,
		
		loaddom:function(){
			DOM = $C('DOM').value;
			$C('DOM').destroy();
		},
		
		loadusr:function(){
			this.usr = $C('USR').value;
			$C('USR').destroy();
			this.secure = Boolean(this.usr);
			if(!this.secure) return;
			window.queue(this.setPublicKey);
			this.locality = this.usr.locality
			this.usr.fresh = Boolean($C('sayhello').value);
			if(this.usr.fresh){
				$C('sayhello').destroy();
				this.fire('loggedin');
			}
			this.fire('usr:loaded');
		},
		
		setPublicKey:function(){
			Smernel.mkSilentIframe('http://'+DOM.name+'/?smuoi_set_pubkey='+pubkey());
		},
		
		reauthenticate:function(){
			Smernel.secure = false;
			Smernel.callAuthHandler();
		},
		
		callAuthHandler:function(){
			window.location.href = '/?login'
		},
		
		readPaths:function(){
			var s = $('Smuoi.js').src;
			this.js_base =  s.substring(0, s.lastIndexOf('/Smuoi.js'));
			this.chrome_path  = s.substring(0, s.lastIndexOf('/js/Smuoi.js'));
			this.public_base = s.substring(0, s.lastIndexOf('/smrnl/'+this.version+'/js/Smuoi.js'));
			this.app_base = this.public_base + '/Apps';
		},
	
		include:function(n){
			document.include(this.js_base + '/' + n)	
		},
		
		mkIframe:function(o, src){
			if(!o) o = {}
			if(!src) src = this.js_base + '/iframe.html';
			var f = mk('iframe', o);
			f.src = src;
			f.style.width  = Object.isNumber(o.width)  ? o.width + 'px'  : '100%';
			f.style.height = Object.isNumber(o.height) ? o.height : window.clientHeight +'px';
			f.frameBorder = 0;
			f.loaded = false;
			return f;
		},
		
		mkSilentIframe:function(src){
			var iframe = this.mkIframe({width:0,height:0}, src);
			iframe.style.display = 'none';
			$U('body').appendChild(iframe);
		},
		
		begin:function(){
			this.loaddom();
			this.loadusr();
			this.readPaths();
		}
	});
	
	var reauthenticate = Smernel.reauthenticate.bind(Smernel);
	
	Smernel.begin();
		
	var usr = function(){
		return Smernel.usr;	
	}
	
	var pubkey = function(){
		return $C('pubkey').value;	
	}
	
	var getcwd = function(){
		var d = dirname(window.location.pathname);
		if(d.substr(d.length-1) == '/') d = d.substr(0, d.length-1)
		if(d.substr(0, 2) != '/@') return 'desk:' + d;
		var sig = d.substr(2, 4);
		switch(sig){
			case 'docs':
			case 'desk':
				return sig + ':' + d.substr(6);
			default:
				return 'desk:/';
		}
	}

	var Chrome = {	
		file_uri:function(filename, sub){
			sub = (!sub) ? '' : (sub.substr(-1) != '/') ? sub + '/' : sub;
			return Smernel.chrome_path + '/' + sub + filename;
		},
		icon_uri:function(icon, size){
			if(!size) size = 32;
			return this.file_uri(icon, 'images/' + size);
		},
		app_icon:function(app, size, property){
			if(!size) size = 32;
			if(!property) property = 'icon'
			return (app[property] && app.modpath) ? Smernel.app_base + '/' + app.modpath + '/images/' + size + '/' + app[property] : this.icon_uri(app[property], size); 
		},
		load:function(){
			
		}
	}
		
	Object.extend(Smajax, {
			
		status_guardian:function(){
			if(!Smernel.secure) return;
			var t = new Date().getTime();
			var lxt = parseInt($C('lxt').value) || t;
			if(Smajax.waiting && !Smajax.confcancel && lxt+Smajax.wait_threshold < t){
				if(Smajax.wait_threshold > 30000){
					if(Smajax.dumtedum) return
					Smajax.dumtedum = true;
					return justsay('Dum te dum te dum...');
				}
				/* Does nothing useful
				var conf = function(a){
					Smajax.confcancel = 1;
					clearInterval(Smajax.int);
					if(a) Smajax.cancel();	
				}
				TUXconfirm('The server is taking a long time.  Do you want to cancel the request?', conf);
				Smajax.int = setInterval(function(){ if(!Smajax.waiting) TUX.rtn(0) }, 1000);*/
			}else if(lxt+300000 < t){
				Smajax.connect('/', {ping:1});
			}
		},

		errorHandlers:{
			0:function(){
				justsay('The server is not reponding')	
			},
			401:function(){
				reauthenticate();	
			}
		},
		
		login:function(n, p, h){
			if(usr()) Smernel.observe('usr:loaded', Smajax.loggedin);
			var pdata = {name:n, passwd:p}
			if(h) pdata.hold = 1
			Smajax.connect('/?login', pdata);
		},
		
		// get_salt is only called when the user is currently logged in
		getsalt:function(){
		 	Smajax.connect('/', {getsalt:1});
		},
		
		setsalt:function(s){
			Chrome.salt = s;
		},
		
		loggedin:function(){
			Smajax.loggeout = false;
			if(Smajax.lastCall) Smajax.exec(Smajax.lastCall.method, Smajax.lastCall.args, 
				Smajax.lastCall.uri, Smajax.lastCall.callback);
			// A quick ping ensures pubkey is created and FRESH_LOGIN is not still set on next page hit
			else Smajax.exec('ping');
		},
	});
	
	var getsalt = Smajax.getsalt.bind(Smajax), setsalt = Smajax.setsalt.bind(Smajax);
	if(usr()) setInterval(Smajax.status_guardian, 2000);

// 	Event listeners

	function addEvent(obj, type, fn){
		if(obj.addEventListener){
			obj.addEventListener( type, fn, false );
		}else if(obj.attachEvent){
			obj["e"+type+fn] = fn;
			obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
			obj.attachEvent( "on"+type, obj[type+fn] );
		}
	}

	function removeEvent(obj, type, fn){
		if(obj.removeEventListener){
			obj.removeEventListener( type, fn, false );
		}else if(obj.detachEvent){
			obj.detachEvent("on"+type, obj[type+fn]);
			obj[type+fn] = null;
			obj["e"+type+fn] = null;
		}
	}
	
	function UnixToDate(u){
		var d = new Date();
		d.setTime(u*1000);
		return d.toUTCString();	
	}
	
	function UnixToTime(u){
		var d = UnixToDate(u);
		return d.replace(/\d\d:/, '|'+/\d\d:/.exec(d)).split('|')[1];
	}
	
